package cn.murky.tenant.system.biz.api;

import cn.murky.common.constant.DictContant;
import cn.murky.core.exception.ServiceException;
import cn.murky.core.record.PasswordRecord;
import cn.murky.core.utils.EncryptionUtil;
import cn.murky.tenant.core.SecurityTenantUserInfo;
import cn.murky.tenant.core.utils.SecurityUtils;
import cn.murky.tenant.system.api.TenantUserApi;
import cn.murky.tenant.system.api.domain.UserProfile;
import cn.murky.tenant.system.api.domain.bo.SysDictDataBO;
import cn.murky.tenant.system.api.domain.bo.TenantUserBO;
import cn.murky.tenant.system.api.domain.dto.ProfileFromDTO;
import cn.murky.tenant.system.biz.convert.TenantUserConvert;
import cn.murky.tenant.system.biz.domian.dto.ResetPasswordDTO;
import cn.murky.tenant.system.biz.domian.entity.*;
import cn.murky.tenant.system.biz.mapper.SysDeptAncestorsMapper;
import cn.murky.tenant.system.biz.mapper.SysRoleMapper;
import cn.murky.tenant.system.biz.mapper.TenantPermissionGroupMapper;
import cn.murky.tenant.system.biz.service.ISysDeptService;
import cn.murky.tenant.system.biz.service.ISysDictDataService;
import cn.murky.tenant.system.biz.service.ITenantService;
import cn.murky.tenant.system.biz.service.ITenantUserService;
import org.noear.solon.Utils;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.List;

import static cn.murky.tenant.system.api.constant.ErrorConstant.LANGUAGE_NOT_SUPPORT;
import static cn.murky.tenant.system.api.constant.ErrorConstant.OLD_PASSWORD_ERROR;

/**
 * 租户用户api
 */
@Component
public class TenantUserApiImpl implements TenantUserApi {
    @Inject
    private ITenantUserService iTenantUserService;
    @Inject
    private ISysDictDataService iSysDictDataService;
    @Inject
    private SysRoleMapper sysRoleMapper;
    @Inject
    private SysDeptAncestorsMapper sysDeptAncestorsMapper;
    @Inject
    private ISysDeptService iSysDeptService;
    @Inject
    private ITenantService iTenantService;
    @Inject
    private TenantPermissionGroupMapper tenantPermissionGroupMapper;
    @Override
    public TenantUserBO getById(Long id) {
        TenantUser tenantUser = iTenantUserService.getById(id);
        return TenantUserConvert.INSTANCES.toBO(tenantUser);

    }

    @Override
    public TenantUserBO getOneByAccount(String account) {
        TenantUser tenantUser = iTenantUserService.getByAccount(account);
        return TenantUserConvert.INSTANCES.toBO(tenantUser);
    }

    @Override
    public boolean setLanguage(String language) {
        List<SysDictDataBO> list = iSysDictDataService.getDict(DictContant.I18N_LANGUAGE_DICT_KEY)
                .stream().filter(item -> item.getDictValue().equals(language)).toList();
        if (Utils.isEmpty(list)) {
            throw new ServiceException(LANGUAGE_NOT_SUPPORT);
        }
        TenantUser tenantUser = new TenantUser()
                .setFkTenantId(SecurityUtils.getTenantId())
                .setId(SecurityUtils.getUserId())
                .setLanguage(language);
        boolean b = iTenantUserService.updateById(tenantUser);
        if (b) {
            SecurityTenantUserInfo userInfo = SecurityUtils.getUserInfo();
            userInfo.setLanguage(language);
            SecurityUtils.setUserInfo(userInfo);
            return true;
        }
        return false;
    }

    @Override
    public UserProfile getProfile(Long userId) {
        UserProfile userProfile = new UserProfile();
        TenantUser tenantUser = iTenantUserService.getById(userId);
        if (SecurityUtils.isAdmin()) {
            Tenant tenant = iTenantService.getById(SecurityUtils.getTenantId());
            TenantPermissionGroup tenantPermissionGroup = tenantPermissionGroupMapper.selectOneById(tenant.getFkGroupId());
            userProfile.setRoleName(tenantPermissionGroup.getGroupName());
        }else{
            SysRole sysRole = sysRoleMapper.selectOneById(tenantUser.getFkRoleId());
            userProfile.setRoleName(sysRole.getRoleName());
        }

        List<Long> deptIds = sysDeptAncestorsMapper.getListByDeptId(tenantUser.getFkDeptId()).stream().map(SysDeptAncestors::getAncestors).toList();
        if(tenantUser.getFkDeptId()!=null){
            deptIds.add(tenantUser.getFkDeptId());
        }
        List<String> deptNameList = iSysDeptService.listByIds(deptIds).stream().map(SysDept::getDeptName).toList();
        return userProfile.setUserName(tenantUser.getUserName())
                .setSex(tenantUser.getSex())
                .setEmail(tenantUser.getEmail())
                .setCreateTime(tenantUser.getCreateTime())
                .setDeptNameList(deptNameList)
                ;
    }

    @Override
    public boolean setProfile(ProfileFromDTO profileFromDTO) {
        TenantUser tenantUser = iTenantUserService.getById(SecurityUtils.getUserId());
        return tenantUser.setUserName(profileFromDTO.getUserName())
                .setEmail(profileFromDTO.getEmail())
                .setSex(profileFromDTO.getSex()).updateById();
    }

    @Override
    public boolean setPassword(String oldPassword, String password, String surePassword) {
        Long userId = SecurityUtils.getUserId();
        TenantUser tenantUser = iTenantUserService.getById(SecurityUtils.getUserId());
        String encryPassword = EncryptionUtil.userEncryption(new PasswordRecord(tenantUser.getSalt(), oldPassword));
        if(!tenantUser.getPassword().equals(encryPassword)){
            throw new ServiceException(OLD_PASSWORD_ERROR);
        }
        return iTenantUserService.resetPassword(new ResetPasswordDTO()
                .setPassword(password)
                .setConfirmPassword(surePassword)
                .setId(userId));
    }
}
